import Dexie from 'dexie'
import 'dexie-observable'

import {
  TransferItem,
  EVENT_TRANSFER_QUERY,
  EVENT_TRANSFER_UPDATED,
  EVENT_TRANSFER_ADD,
  EVENT_TRANSFER_DELETE_DB,
  EVENT_TRANSFER_UPDATE_ITEM
} from './enum'
import {
  windowOnEvent,
  windowDispatch
} from '../utils/events'

class MyDatabase {
  constructor(config = {}) {
    const {
      dbName = 'TransferDB',
      tableName = 'transferTable'
    } = config

    this.db = new Dexie(dbName)

    const transferListSchema = new TransferItem()
    delete transferListSchema.id

    const schema = '++id,' + Object.keys(transferListSchema).join(',')
    console.log({schema})

    this.db.version(1).stores({
      [tableName]: schema
    })

    this.table = this.db[tableName]

    // 观察数据变化
    this.db.on('changes', (changes) => {
      windowDispatch(EVENT_TRANSFER_UPDATED, {changes})
    })

    this.db.transaction('rw', this.table, async () => {
      // init action here
    }).catch(e => {
      console.error('transaction failed', e)
    })

    // 查询
    this.query = async (data = {}) => {
      const {
        where,
        anyOf,
        offset = 0,
        limit = 50,
        isDelete = false, // 是否删除
        isReverse = false, // 是否倒序
        cbSuccess,
        cbError
      } = data
      try {
        let query = this.table

        if (where && Object.keys(where).length) {
          query = query.where(where)
        }

        if (anyOf) {
          query = query.anyOf(anyOf)
        }

        if (isDelete) {
          const deleteCount = await query.delete()
          return cbSuccess(deleteCount)
        }

        const totalCount = await query.count()

        if (isReverse) {
          query = query.reverse()
        }

        const list = await query.offset(offset).limit(limit).toArray()

        cbSuccess({
          totalCount,
          list
        })
      } catch (e) {
        cbError(e)
      }
    }

    // 添加项
    this.addItem = async (data = {}) => {
      const {item, cbSuccess, cbError} = data
      if (!item) {
        return cbError(new Error('item 不能为空'))
      }

      try {
        const id = await this.table.add(item)
        item.id = id

        cbSuccess({id})
      } catch (e) {
        cbError(e)
      }
    }

    // 删库
    this.deleteDatabase = async (data = {}) => {
      const {cbSuccess, cbError} = data

      try {
        this.db.close()
        const result = await Dexie.delete(dbName)
        await this.db.open()
        cbSuccess(result)
      } catch (e) {
        cbError(e)
      }
    }

    // 更新项
    this.updateItem = async (data = {}) => {
      const {
        item,
        update = {},
        cbSuccess,
        cbError
      } = data

      try {
        await this.table.update(item.id, update)
        cbSuccess()
      } catch (e) {
        cbError(e)
      }
    }

    this.registerEvents()
  }

  registerEvents() {
    windowOnEvent(EVENT_TRANSFER_QUERY, this.query)
    windowOnEvent(EVENT_TRANSFER_ADD, this.addItem)
    windowOnEvent(EVENT_TRANSFER_DELETE_DB, this.deleteDatabase)
    windowOnEvent(EVENT_TRANSFER_UPDATE_ITEM, this.updateItem)
  }
}


export default new MyDatabase()
